package ex406.util;

public class ArrayQueue<E> {
    private Object[] elements = {}; // 存放队列元素的数组
    private int front = 0;   // 队首
    private int rear = 0;    // 队尾

    /**
     * 无参构造方法，创建默认容量为16的队列
     */
    public ArrayQueue() {
        this(16);
    }

    /**
     * 创建容量创建默认容量为initialCapacity的队列
     *
     * @param initialCapacity
     */
    public ArrayQueue(int initialCapacity) {
        if (initialCapacity <= 0) {
            throw new IllegalArgumentException("队列容量必须大于0.");
        }
        // 为了方便判断队列满，数组中有一个元素没有被队列使用
        elements = new Object[initialCapacity + 1];
    }

    /**
     * 判断队列是否为空
     *
     * @return true-队列为空; false-队列不为空
     */
    public boolean isEmpty() {
        return front == rear; // 队首下标等于队尾下标时队列为空
    }

    /**
     * 判断队列是否为满
     *
     * @return true-队列满; false-队列未满
     */
    public boolean isFull() {
        return (rear + 1) % elements.length == front; //队尾下标加1等于队首指针是队列满
    }

    /**
     * 向队列添加元素 element
     *
     * @param element
     * @Throws 如果队列已满，抛出IllegalStateException异常
     */
    public void add(E element) {
        if (this.isFull()) {
            throw new IllegalStateException("队列已满.");
        }
        elements[rear] = element;
        rear = (rear + 1) % elements.length;
    }

    /**
     * 删除并返回队首元素
     *
     * @return 队首元素
     * @Throws 如果队列为空，抛出IllegalStateException异常
     */
    public E remove() {
        if (this.isEmpty()) {
            throw new IllegalStateException("队列为空.");
        }
        E temp = (E) elements[front];
        front = (front + 1) % elements.length;
        return temp;
    }
}
